//============================================================================================
/**
 * @file	rock_result.c
 * @brief
 * @date	2009.01.09
 * @author	NozomuSaito GAME FREAK inc.
 *
 * モジュール名：RockRslt_
 */
//============================================================================================

#include "common.h"
#include "fieldsys.h"
#include "encount_set.h"
#include "field_encount.h"
#include "battle/tokusyu_def.h"
#include "itemtool/itemsym.h"
#include "rock_result.h"

#define ROCK_ITEM_NUM	(8)
#define	TBL_NUM_MAX 	(3)

typedef struct ROCK_ZONE_DATA_tag
{
	u16 Prob;
	u16 TblNo;
}ROCK_ZONE_DATA;

typedef struct ROCK_ITEM_WORK_tag
{
	BOOL IsPair;
	int Spa;
	u16 *AnsWk;
	u16 *ItemWk;
	ROCK_ZONE_DATA RockZone;
	EOA_PTR EoaPtr;
}ROCK_ITEM_WORK;

static BOOL RockRsltEvt(GMEVENT_CONTROL *event);

static BOOL CheckItemGet(FIELDSYS_WORK *fsys, ROCK_ITEM_WORK *riw);
static BOOL ItemGetEvt(GMEVENT_CONTROL *event);
static u8 GetItemTblIdx(void);

//バージョン共通
static const u16 RockItemTbl1[ROCK_ITEM_NUM] = {
	ITEM_PIIPIIRIKABAA,
	ITEM_GENKINOKAKERA,
	ITEM_HAATONOUROKO,
	ITEM_AKAIKAKERA,
	ITEM_AOIKAKERA,
	ITEM_MIDORINOKAKERA,
	ITEM_KIIROIKAKERA,
	ITEM_HOSINOKAKERA,
};

//金バージョン
#if (PM_VERSION == VERSION_GOLD )
static const u16 RockItemTbl2[ROCK_ITEM_NUM] = {
	ITEM_AKAIKAKERA,
	ITEM_KIIROIKAKERA,
	ITEM_KAINOKASEKI,
	ITEM_PIIPIIRIKABAA,
	ITEM_AOIKAKERA,
	ITEM_MIDORINOKAKERA,
	ITEM_HIMITUNOKOHAKU,
	ITEM_GENKINOKATAMARI,
};

static const u16 RockItemTbl3[ROCK_ITEM_NUM] = {
	ITEM_PIIPIIRIKABAA,
	ITEM_SINZYU,
	ITEM_OOKINASINZYU,
	ITEM_AKAIKAKERA,
	ITEM_KIIROIKAKERA,
	ITEM_TUMENOKASEKI,
	ITEM_TUMENOKASEKI,
	ITEM_KITYOUNAHONE,
};
#else
//銀バージョン
static const u16 RockItemTbl2[ROCK_ITEM_NUM] = {
	ITEM_AOIKAKERA,
	ITEM_MIDORINOKAKERA,
	ITEM_KOURANOKASEKI,
	ITEM_PIIPIIRIKABAA,
	ITEM_AKAIKAKERA,
	ITEM_KIIROIKAKERA,
	ITEM_HIMITUNOKOHAKU,
	ITEM_GENKINOKATAMARI,
};

static const u16 RockItemTbl3[ROCK_ITEM_NUM] = {
	ITEM_PIIPIIRIKABAA,
	ITEM_SINZYU,
	ITEM_OOKINASINZYU,
	ITEM_AOIKAKERA,
	ITEM_MIDORINOKAKERA,
	ITEM_NEKKONOKASEKI,
	ITEM_NEKKONOKASEKI,
	ITEM_KITYOUNAHONE,
};
#endif


//--------------------------------------------------------------
/**
 * 岩砕き使用後のイベント判定
 * @param	fsys		フィールドシステムポインタ
 * @param	inIsPair	連れ歩きが岩砕きしたか
 * @param	ans_wk		アンサーワークポインタ
 * @param	itemno		アイテムナンバー格納バッファ
 *
 * @retval	none
 */
//--------------------------------------------------------------
void RockRslt_CallEvt(FIELDSYS_WORK *fsys, const u8 inIsPair, u16 *ans_wk, u16 *itemno)
{
	ROCK_ITEM_WORK *riw;
	riw = sys_AllocMemoryLo(HEAPID_WORLD, sizeof(ROCK_ITEM_WORK));

	if (inIsPair){
		riw->IsPair = TRUE;
	}else{
		riw->IsPair = FALSE;
	}

	riw->AnsWk = ans_wk;
	riw->ItemWk = itemno;
	*riw->AnsWk = 0;
	*riw->ItemWk = 0;

	FieldEvent_Call(fsys->event, RockRsltEvt, riw);
}

//--------------------------------------------------------------
/**
 * 岩砕き後イベント
 * @param	event	GMEVENT_CONTROL *
 * @retval	int		TRUE=終了
 */
//--------------------------------------------------------------
static BOOL RockRsltEvt(GMEVENT_CONTROL *event)
{
	BOOL rc;
	BATTLE_PARAM *bt_param;
	FIELDSYS_WORK *fsys = FieldEvent_GetFieldSysWork( event );
	ROCK_ITEM_WORK *wk = (ROCK_ITEM_WORK*) FieldEvent_GetSpecialWork(event);

	//エンカウントチェック
	rc = SetRockEncount( fsys, &bt_param );
	if ( rc ){
		//リターン値セット
		*wk->AnsWk = 0;		//アイテム入手なし
		*wk->ItemWk = 0;
		//アイテムワークは不要なので解放
		sys_FreeMemoryEz(wk);
		FieldEncount_Change( fsys, event, bt_param );
		return FALSE;
	}else{	//かけら入手イベント
		//アイテム発生チェック
		if ( CheckItemGet(fsys, wk) ){
			//イベントチェンジ
			FieldEvent_Change(event, ItemGetEvt, wk);
			return FALSE;
		}
		//リターン値セット
		*wk->AnsWk = 0;		//アイテム入手なし
		*wk->ItemWk = 0;
		//アイテムワークは不要なので解放
		sys_FreeMemoryEz(wk);
	}
	return TRUE;
}

//--------------------------------------------------------------
/**
 * アイテム入手チェック
 * @param	fsys		フィールドシステムポインタ
 * @param	riw			岩砕きアイテムワークポインタ
 *
 * @retval	BOOL
 */
//--------------------------------------------------------------
static BOOL CheckItemGet(FIELDSYS_WORK *fsys, ROCK_ITEM_WORK *riw)
{
	int prob;
	int spa;
	int zone_id;

	ROCK_ZONE_DATA rock_zone;

	zone_id = fsys->location->zone_id;
	ArchiveDataLoad(&rock_zone, ARC_ROCK_ZONE_DATA, zone_id);

	if (rock_zone.Prob == 0){
		return FALSE;
	}

	if (rock_zone.TblNo >= TBL_NUM_MAX){
		GF_ASSERT_MSG(0,"テーブルオーバー\n");
		return FALSE;
	}

	//ベースの出現確率をアーカイブから取得
	prob = rock_zone.Prob;

	//先頭ポケモンの特性を取得
	{
		POKEMON_PARAM *poke_param;
		POKEPARTY *my_party;
		//手持ちポケパーティ取得
		my_party = SaveData_GetTemotiPokemon(fsys->savedata);
		poke_param = PokeParty_GetMemberPointer(my_party, 0);	//先頭ポケモン取得

		//先頭ポケモンのタマゴチェック
		if( PokeParaGet( poke_param, ID_PARA_tamago_flag, NULL ) == 0 ){
			// 先頭のポケモンがタマゴでない
			spa = PokeParaGet(poke_param, ID_PARA_speabino, NULL);	// 特殊能力取得
		}else{
			// 先頭のポケモンがタマゴ
			spa = TOKUSYU_MAX;
		}
	}

	//特性格納
	riw->Spa = spa;

	//特性による確率変動
	switch(spa){
	case TOKUSYU_KYUUBAN:
		prob+=5;
		break;
	case TOKUSYU_ZIRYOKU:
		prob+=5;
		break;
	case TOKUSYU_SURUDOIME:
		prob+=5;
		break;
	}

	//岩砕きを使用したのが連れ歩きポケか？
	if(riw->IsPair){
		prob+=5;
	}

	//確率は最大100
	if (prob > 100){
		prob = 100;
	}

	if ( gf_rand()%100 < prob ){
		riw->RockZone = rock_zone;
		return TRUE;
	}
	return FALSE;
}

//--------------------------------------------------------------
/**
 * アイテム取得イベント
 * @param	event	GMEVENT_CONTROL *
 * @retval	int		TRUE=終了
 */
//--------------------------------------------------------------
static BOOL ItemGetEvt(GMEVENT_CONTROL *event)
{
	int *seq;
	ROCK_ITEM_WORK *wk;
	FIELDSYS_WORK *fsys;

	seq = FieldEvent_GetSeqWork(event);
	wk = (ROCK_ITEM_WORK*) FieldEvent_GetSpecialWork(event);
	fsys = FieldEvent_GetFieldSysWork(event);

	switch(*seq){
	case 0:
		{
			FIELD_OBJ_PTR fldobj;
			//「！」表示
			if (wk->IsPair){
				//連れ歩きに出す
				fldobj = PairPoke_GetFldObjPtr(fsys);
			}else{
				//自機に出す
				fldobj = Player_FieldOBJGet( fsys->player );
			}
			wk->EoaPtr = FE_FldOBJGyoe_Add( fldobj, GYOE_GYOE, TRUE );
		}
		(*seq)++;
		break;
	case 1:
		//「！」待ち
		if ( FE_Gyoe_EndCheck( wk->EoaPtr ) ){
			EOA_Delete( wk->EoaPtr );
			(*seq)++;
		}
		break;
	case 2:
		{
			u16 item;
			//アイテムテーブル抽選
			u8 idx = GetItemTblIdx();
			//特性により、アイテムテーブル番号をシフト
			switch(wk->Spa){
			case TOKUSYU_KYOUUN:
			case TOKUSYU_TENNOMEGUMI:
				if (idx < ROCK_ITEM_NUM-1){
					idx++;
				}
				break;
			}

			GF_ASSERT(idx < ROCK_ITEM_NUM);

			//発生　ゾーンチェック
			switch (wk->RockZone.TblNo){
			case 0:
				item = RockItemTbl1[idx];
				break;
			case 1:
				item = RockItemTbl2[idx];
				break;
			case 2:
				item = RockItemTbl3[idx];
				break;
			default:
				GF_ASSERT(0);
				*wk->AnsWk = 0;		//アイテム入手なし
				*wk->ItemWk = 0;
				sys_FreeMemoryEz(wk);
				return TRUE;
			}

			OS_Printf("掘り出しアイテム%d\n",item);

			//アンサーワークに1をいれ、ワークにアイテム番号を入れて返す
			*wk->AnsWk = 1;
			*wk->ItemWk = item;
		}
		//ワーク解放
		sys_FreeMemoryEz(wk);
		return TRUE;
	}
	return FALSE;
}

//--------------------------------------------------------------
/**
 * アイテム抽選
 * @param	none
 * @retval	idx		テーブルインデックス
 */
//--------------------------------------------------------------
static u8 GetItemTblIdx(void)
{
	u8 idx;
	u8 prob = gf_rand()%100;
	if (prob < 25){				//25％
		idx = 0;
	}else if(prob < 45){		//20％
		idx = 1;
	}else if(prob < 55){		//10％
		idx = 2;
	}else if(prob < 65){		//10％
		idx = 3;
	}else if(prob < 75){		//10％
		idx = 4;
	}else if(prob < 85){		//10％
		idx = 5;
	}else if(prob < 95){		//10％
		idx = 6;
	}else{						//5%
		idx = 7;
	}

	return idx;
}
